package com.linko.intelligent.common.util;

import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import jodd.util.StringUtil;
import okhttp3.*;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class HttpUtil {

    private static final Logger logger = LoggerFactory.getLogger(HttpUtil.class);

    public static OkHttpClient client = new OkHttpClient().newBuilder().readTimeout(10, TimeUnit.SECONDS).build();

    private HttpUtil() {
    }

    ;

    public static void request(String url, Long requestMethod, Long contentType, String jsonData, Callback callback) {
        RequestBody requestBody = null;
        if (0L == contentType) {
            MediaType mediaType = MediaType.parse("application/json");
            requestBody = RequestBody.create(mediaType, jsonData);
        } else if (1L == contentType) {
            MultipartBody.Builder bodyBuilder = new MultipartBody.Builder().setType(MultipartBody.FORM);
            if (StringUtil.isNotBlank(jsonData)) {
                JSONObject dataJson = JSONObject.parseObject(jsonData);
                for (String key : dataJson.keySet()) {
                    bodyBuilder.addFormDataPart(key, dataJson.getString(key));
                }
            }
            requestBody = bodyBuilder.build();
        }
        Request request = null;
        if (requestMethod == 0L) {
            HttpUrl httpUrl = HttpUrl.parse(url);
            if (StringUtil.isNotBlank(jsonData)) {
                HttpUrl.Builder urlBuilder = HttpUrl.parse(url).newBuilder();
                JSONObject dataJson = JSONObject.parseObject(jsonData);
                for (String key : dataJson.keySet()) {
                    urlBuilder.addQueryParameter(key, dataJson.getString(key));
                }
                httpUrl = urlBuilder.build();
            }
            Request.Builder builder = new Request.Builder()
                    .url(httpUrl)
                    .get();
            request = builder.build();
        } else if (requestMethod == 1L) {
            Request.Builder builder = new Request.Builder()
                    .url(url)
                    .post(requestBody);
            request = builder.build();
        } else if (requestMethod == 2L) {
            Request.Builder builder = new Request.Builder()
                    .url(url)
                    .put(requestBody);
            request = builder.build();
        } else if (requestMethod == 3L) {
            Request.Builder builder = new Request.Builder()
                    .url(url)
                    .delete();
            request = builder.build();
        }
        Call call = client.newCall(request);
        call.enqueue(callback);
    }

    public static void get(String url, Callback callback) {
        Request request = new Request.Builder()
                .url(url)
                .get()
                .build();
        Call call = client.newCall(request);
        call.enqueue(callback);
    }

    public static Response get(String url, Map<String, String> header) {
        Request.Builder builder = new Request.Builder()
                .url(url)
                .get();
        if (header != null) {
            for (Map.Entry<String, String> entry : header.entrySet()) {
                builder.addHeader(entry.getKey(), entry.getValue());
            }
        }

        Request request = builder.build();

        Call call = client.newCall(request);
        Response response = null;
        try {
            response = call.execute();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return response;
    }

    public static Response post(String url, Map<String, String> reqBody, Map<String, String> header) {
        MediaType mediaType = MediaType.parse("application/json");
        RequestBody requestBody = RequestBody.create(mediaType, new Gson().toJson(reqBody));
        Request.Builder builder = new Request.Builder()
                .url(url)
                .post(requestBody);
        if (header != null) {
            for (Map.Entry<String, String> entry : header.entrySet()) {
                builder.addHeader(entry.getKey(), entry.getValue());
            }
        }

        Request request = builder.build();
        Call call = client.newCall(request);
        Response response = null;
        try {
            response = call.execute();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return response;
    }

    public static Response post(String url, Object reqBody, Map<String, String> header) {
        MediaType mediaType = MediaType.parse("application/json");
        RequestBody requestBody = RequestBody.create(mediaType, new Gson().toJson(reqBody));
        Request.Builder builder = new Request.Builder()
                .url(url)
                .post(requestBody);
        if (header != null) {
            for (Map.Entry<String, String> entry : header.entrySet()) {
                builder.addHeader(entry.getKey(), entry.getValue());
            }
        }

        Request request = builder.build();
        Call call = client.newCall(request);
        Response response = null;
        try {
            response = call.execute();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return response;
    }

    public static Response post(String url, Object reqBody) {
        MediaType mediaType = MediaType.parse("application/json");
        RequestBody requestBody = RequestBody.create(mediaType, new Gson().toJson(reqBody));
        Request.Builder builder = new Request.Builder()
                .url(url)
                .post(requestBody);

        Request request = builder.build();
        Call call = client.newCall(request);
        Response response = null;
        try {
            response = call.execute();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return response;
    }

    public static <T> T post(String url, Object reqBody, Class<T> clazz) {
        MediaType mediaType = MediaType.parse("application/json");
        RequestBody requestBody = RequestBody.create(mediaType, new Gson().toJson(reqBody));
        Request.Builder builder = new Request.Builder()
                .url(url)
                .post(requestBody);
        Request request = builder.build();
        Call call = client.newCall(request);
        T t = null;
        String resBodyStr = null;
        try {
            Response response = call.execute();
            resBodyStr = response.body().string();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (StringUtil.isBlank(resBodyStr)) {
            return t;
        }
        t = new Gson().fromJson(resBodyStr, clazz);
        return t;
    }

    public static Response postText(String url, String str, Map<String, String> header) {
        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody requestBody = RequestBody.create(mediaType, str);
        Request.Builder builder = new Request.Builder()
                .url(url)
                .post(requestBody);
        if (header != null) {
            for (Map.Entry<String, String> entry : header.entrySet()) {
                builder.addHeader(entry.getKey(), entry.getValue());
            }
        }

        Request request = builder.build();
        Call call = client.newCall(request);
        Response response = null;
        try {
            response = call.execute();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return response;
    }

    public static Response postParam(String url, Map<String, String> reqBody, Map<String, String> header) {
        MultipartBody.Builder bodyBuilder = new MultipartBody.Builder().setType(MultipartBody.FORM);
        if (reqBody != null) {
            for (String key : reqBody.keySet()) {
                bodyBuilder.addFormDataPart(key, reqBody.get(key));
            }
        }

        Request.Builder builder = new Request.Builder()
                .url(url)
                .post(bodyBuilder.build());
        if (header != null) {
            for (Map.Entry<String, String> entry : header.entrySet()) {
                builder.addHeader(entry.getKey(), entry.getValue());
            }
        }
        Request request = builder.build();
        Call call = client.newCall(request);
        Response response = null;
        try {
            response = call.execute();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return response;

    }

    ;

    public static Response delete(String url, Map<String, String> header) {
        Request.Builder builder = new Request.Builder()
                .url(url)
                .delete();
        for (Map.Entry<String, String> entry : header.entrySet()) {
            builder.addHeader(entry.getKey(), entry.getValue());
        }
        Request request = builder.build();
        Call call = client.newCall(request);
        Response response = null;
        try {
            response = call.execute();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return response;
    }

    public static Response put(String url, Map<String, String> reqBody, Map<String, String> header) {
        MediaType mediaType = MediaType.parse("application/json");
        RequestBody requestBody = RequestBody.create(mediaType, new Gson().toJson(reqBody));
        Request.Builder builder = new Request.Builder()
                .url(url)
                .put(requestBody);
        for (Map.Entry<String, String> entry : header.entrySet()) {
            builder.addHeader(entry.getKey(), entry.getValue());
        }
        Request request = builder.build();
        Call call = client.newCall(request);
        Response response = null;
        try {
            response = call.execute();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return response;
    }


    public static <T> T parseRes(Response response, Class<T> clazz) {
        String bodyStr = null;
        T t = null;
        try {
            bodyStr = response.body().string();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (bodyStr != null) {
            t = new Gson().fromJson(bodyStr, clazz);
        }
        return t;
    }

    /**
     * @param url
     * @param jsonObj
     * @return
     * @throws ClientProtocolException
     * @throws IOException
     */
    public static JSONObject sendPost(String url, JSONObject jsonObj) {
        logger.info("sendPost请求入参---->url:{},data:{}", url, jsonObj);
        try {
            CloseableHttpClient httpClient = HttpClients.createDefault();
            HttpPost httpPost = new HttpPost(url);
            //添加基础超时配置
            RequestConfig requestConfig = RequestConfig.custom()
                    .setSocketTimeout(10000).setConnectTimeout(10000)
                    .setConnectionRequestTimeout(10000).build();
            httpPost.setConfig(requestConfig);
            StringEntity strEntity = new StringEntity(JSONObject.toJSONString(jsonObj), "utf-8");
            //设置回调接口接收的消息头
            httpPost.addHeader("Content-Type", "application/json");
            httpPost.setEntity(strEntity);
            //执行
            CloseableHttpResponse response = httpClient.execute(httpPost);
            //输出调用结果
            if (response != null && response.getStatusLine().getStatusCode() == 200) {
                //获取的数据转换
                String result = EntityUtils.toString(response.getEntity(), "UTF-8");
                if (StringUtil.isNotEmpty(result)) {
                    JSONObject object = JSONObject.parseObject(result);
                    return object;
                }
            }
            logger.error("sendPost请求状态异常---->url:{},data:{},statusCode:{}", url, jsonObj, response.getStatusLine().getStatusCode());
        } catch (Exception e) {
            logger.error("sendPost请求异常---->url:{},data:{}", url, jsonObj, e);
        }
        return null;
    }
}
